package com.lngsyz.ywtb.biz.service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lngsyz.ywtb.entity.LoginInfo;
import com.lngsyz.ywtb.entity.biz.AddElecOrder;
import com.lngsyz.ywtb.entity.biz.AddPhyOrder;
import com.lngsyz.ywtb.entity.biz.CurrentInfo;
import com.lngsyz.ywtb.entity.biz.LocalCompany;
import com.lngsyz.ywtb.entity.biz.LocalDistrict;
import com.lngsyz.ywtb.entity.biz.OrderDetail;
import com.lngsyz.ywtb.entity.biz.OrderInfo;
import com.lngsyz.ywtb.entity.biz.PriceInfo;
import com.lngsyz.ywtb.entity.biz.ReferPhySeal;
import com.lngsyz.ywtb.entity.biz.YwtbCompany;
import com.lngsyz.ywtb.entity.source1.SystemCompany;
import com.lngsyz.ywtb.entity.source1.SystemCustom;
import com.lngsyz.ywtb.entity.source1.SystemDic;
import com.lngsyz.ywtb.entity.source1.YwtbCityOrder;
import com.lngsyz.ywtb.entity.source2.TCompany;
import com.lngsyz.ywtb.entity.source2.TCompanyPrice;
import com.lngsyz.ywtb.enumeration.Pay;
import com.lngsyz.ywtb.pay.entity.CreateTradeInfoVO;
import com.lngsyz.ywtb.pay.entity.OutqQueryTransactionOrderDataVO;
import com.lngsyz.ywtb.pay.entity.SealTradeMainInfoVO;
import com.lngsyz.ywtb.pay.exception.RequestSystemException;
import com.lngsyz.ywtb.pay.service.PayService;
import com.lngsyz.ywtb.util.CommonUtil;
import com.lngsyz.ywtb.wx.entity.WxSignature;
import com.lngsyz.ywtb.wx.utils.GetWxSignatureUtil;

import net.logstash.logback.encoder.org.apache.commons.lang.StringUtils;

@Service
public class BizService {
    
	@Autowired
	SystemCompanyService systemCompanyService;
	@Autowired
	TCompanyPriceService tCompanyPriceService;
	@Autowired
	TCompanyService tCompanyService;
	@Autowired
	SystemDicService systemDicService;
	@Autowired
	SystemSealService systemSealService;
	@Autowired
	SystemCustomService systemCustomService;
	@Autowired
	YwtbCityOrderService ywtbCityOrderService;
	@Autowired
	YwtbCityOrderSealService ywtbCityOrderSealService;
	@Autowired
	PayService payService;

    /**
     * 获取订单详情
     * @return
     */
    public CurrentInfo getCurrentInfo(LoginInfo loginInfo) {
    	CurrentInfo rtn = new CurrentInfo();
    	if(loginInfo != null) {
    		rtn.setDistrictCity(loginInfo.getDistrictCity());
    		rtn.setCustomName(loginInfo.getName());
    	}
    	return rtn;
    }
	
	/**
	 * 获取属地刻章厂列表
	 * @param district
	 * @param name
	 * @param loginInfo
	 * @param page
	 * @param size
	 * @return
	 */
    public List<LocalCompany> getLocalCompanyList(String district, String name, LoginInfo loginInfo, int page, int size){
    	String districtCity = loginInfo.getDistrictCity();
    	List<SystemCompany> systemCompanys = systemCompanyService.findByCondition(districtCity, district, name, page, size);
    	List<TCompany> tCompanys = tCompanyService.findByCondition(districtCity, district, name);
    	List<String> tCompanyIds = tCompanys.stream().map(TCompany::getId).collect(Collectors.toList());
    	List<LocalCompany> rtn = new ArrayList<LocalCompany>();
    	for(SystemCompany sc : systemCompanys) {
    		LocalCompany tc = new LocalCompany();
    		tc.setName(sc.getName());
    		tc.setAddress(sc.getAddress());
    		tc.setContactMan(sc.getContactman());
    		tc.setContactPhone(sc.getContactphone());
    		tc.setCoordinateX(sc.getCoordinateX());
    		tc.setCoordinateY(sc.getCoordinateY());
    		tc.setYwtbFlag(tCompanyIds.contains(sc.getId()));
    		rtn.add(tc);
    	}
    	return rtn;
    }
    
    public int getLocalCompanyCount(String district, String name, LoginInfo loginInfo) {
    	String districtCity = loginInfo.getDistrictCity();
    	return systemCompanyService.findTotal(districtCity, district, name);
    }

    /**
     * 获取属地地址区划
     * @param loginInfo
     * @return
     */
    public List<LocalDistrict> getLocalDistrict(LoginInfo loginInfo){
    	List<SystemDic> systemDics = systemDicService.findDistrictByCity(loginInfo.getDistrictCity());
    	List<LocalDistrict> rtn = new ArrayList<LocalDistrict>();
    	if(systemDics != null && systemDics.size() > 0) {
    		LocalDistrict ld = new LocalDistrict();
    		ld.setCode("");
    		ld.setValue("全部");
    		rtn.add(ld);
    	}
    	for(SystemDic sd : systemDics) {
    		LocalDistrict ld = new LocalDistrict();
    		ld.setCode(sd.getCode());
    		ld.setValue(sd.getValue());
    		rtn.add(ld);
    	}
    	return rtn;
    }

    /**
     * 根据刻章厂ID获取刻章厂信息和对应印章价格
     * @param companyId
     * @return
     */
    public List<PriceInfo> getPriceByCompanyId(String companyId, String sealMedia){
    	List<TCompanyPrice> tCompanyPrices = tCompanyPriceService.findByCompanyId(companyId, sealMedia);
    	List<PriceInfo> rtn = new ArrayList<PriceInfo>();
    	for(TCompanyPrice tcp : tCompanyPrices) {
    		PriceInfo pi = new PriceInfo();
    		pi.setMaterialType(tcp.getMaterial());
    		pi.setSeal01(tcp.getSeal01());
    		pi.setSeal02(tcp.getSeal02());
    		pi.setSeal03(tcp.getSeal03());
    		pi.setSeal04(tcp.getSeal04());
    		pi.setSeal05(tcp.getSeal05());
    		pi.setSeal06(tcp.getSeal06());
    		rtn.add(pi);
    	}
    	return rtn;
    }

    /**
     * 获取一网通办刻章厂列表
     * @param name
     * @return
     */
    public List<YwtbCompany> getYwtbCompany(String district, String name, String sealMedia, LoginInfo loginInfo){
    	String districtCity = loginInfo.getDistrictCity();
    	List<TCompany> tCompanys = tCompanyService.findByCondition(districtCity, district, name, sealMedia);
    	List<YwtbCompany> rtn = new ArrayList<YwtbCompany>();
    	for(TCompany tc : tCompanys) {
    		YwtbCompany yc = new YwtbCompany();
    		yc.setId(tc.getId());
    		yc.setName(tc.getName());
    		yc.setBusinessLicense(tc.getBusinessLicense());
    		yc.setAddress(tc.getAddress());
    		yc.setContactMan(tc.getContactMan());
    		yc.setContactPhone(tc.getContactPhone());
    		rtn.add(yc);
    	}
    	return rtn;
    }

    /**
     * 添加物理订单
     * @return
     */
    public String addPhyOrder(AddPhyOrder addPhyOrder, LoginInfo loginInfo) throws Exception {
    	// TODO
    	// add logic check
    	ywtbCityOrderService.addPhyOrderCheck(addPhyOrder, loginInfo);
    	// package pay info
    	SealTradeMainInfoVO createPayBean = payService.packageCreatePayBean(addPhyOrder, loginInfo);
    	// create order
    	CreateTradeInfoVO createOrderInfo = payService.createSealTransactionOrderInterface(createPayBean);
    	// get tradeno
    	String tradeNo = createOrderInfo.getTradeNo();
    	addPhyOrder.setTradeNo(tradeNo);
    	// 入库
    	ywtbCityOrderService.addPhyOrder(addPhyOrder, loginInfo);
    	return tradeNo;
    }
    
    /**
     * 添加电子订单
     * @return
     */
    public String addElecOrder(AddElecOrder addElecOrder, LoginInfo loginInfo) throws Exception {
    	// TODO
    	// add logic check
    	ywtbCityOrderService.addElecOrderCheck(addElecOrder, loginInfo);
    	// package pay info
    	SealTradeMainInfoVO createPayBean = payService.packageCreatePayBean(addElecOrder, loginInfo);
    	// create order
    	CreateTradeInfoVO createOrderInfo = payService.createSealTransactionOrderInterface(createPayBean);
    	// get tradeno
    	String tradeNo = createOrderInfo.getTradeNo();
    	//String tradeNo = "A23040707572600978";
    	addElecOrder.setTradeNo(tradeNo);
    	// 入库
    	ywtbCityOrderService.addElecOrder(addElecOrder, loginInfo);
    	return tradeNo;
    }

    /**
     * 获取订单详情
     * @return
     */
    public OrderDetail getOrderDetail(String id) {
    	OrderDetail rtn = new OrderDetail();
    	YwtbCityOrder yco = ywtbCityOrderService.findById(id);
    	if(yco != null) {
    		rtn.setSeals(ywtbCityOrderSealService.findByMainId(yco.getId()));
    		rtn.setCompanyInfo(systemCompanyService.findInfo(yco.getCompanyId()));
    		rtn.setDeliveryInfo(ywtbCityOrderService.packageDelivery(yco));
    		rtn.setTradeInfo(ywtbCityOrderService.packageTrade(yco));
    	}
    	return rtn;
    }
    
    /**
     * 获取订单列表
     * @return
     */
    public List<OrderInfo> getOrderList(LoginInfo loginInfo, String pay){
    	// TODO
    	List<OrderInfo> rtn = new ArrayList<OrderInfo>();
    	String businessLicense = loginInfo.getInstCode();
    	if(StringUtils.isNotBlank(businessLicense)) {
    		List<YwtbCityOrder> ywtbCityOrders = ywtbCityOrderService.findByBusinessLicense(businessLicense, pay);
    		for(YwtbCityOrder yco : ywtbCityOrders) {
    			OrderInfo oi = new OrderInfo();
    			oi.setId(yco.getId());
    			oi.setSeals(ywtbCityOrderSealService.findByMainId(yco.getId()));
    			oi.setCompanyName(systemCompanyService.findNameById(yco.getCompanyId()));
    			oi.setDeliveryMethod(yco.getDeliveryMethod());
    			oi.setPay(yco.getPay());
    			oi.setTradeNo(yco.getTradeno());
    			oi.setGmtCreate(CommonUtil.dateToStrLong(yco.getGmtCreate()));
    			oi.setGmtPay(CommonUtil.dateToStrLong(yco.getZfsj()));
    			oi.setTotal(yco.getTotal());
    			oi.setESeal(StringUtils.equals(yco.getESeal(), "1") ? "1" : "0");
    			rtn.add(oi);
    		}
    	}
    	return rtn;
    }

    /**
     * 强制触发更新订单操作
     * @param orderId
     */
    public void updateOrder(YwtbCityOrder yco) throws Exception {
    	// 支付/未支付的订单可以更新，其他不可以
    	if(yco != null) {
    		System.out.println("#####订单状态：" + Pay.getNameByKey(yco.getPay()));
    		// 检查未支付-->已支付的过程
    		if(StringUtils.equals(yco.getPay(), Pay.PAY_NO.getKey())) {
    			String tradeNo = yco.getTradeno();
    			// String tradeNo = "SL20210104100646680000000012";
    			OutqQueryTransactionOrderDataVO orderData = payService.queryTransactionOrderResultInterface(tradeNo);
    			// 支付成功，或已退款，或已关闭的订单，需要更新
    			if(orderData != null) {
    				if(orderData.getCode() == 0 && orderData.getData() != null) {
    					System.out.println("#####统一支付平台状态：" + Pay.getNameByKey(orderData.getData().getTradeStatus()));
    					String zfsj = orderData.getData().getTradeHandleTime();
    					String pay = orderData.getData().getTradeStatus();
    					String payChannel = orderData.getData().getTradeChannel();
    					// String total = orderData.getData().getPrice();
    					yco.setZfsj(CommonUtil.strToDateLong(zfsj));
    					yco.setPay(pay);
    					yco.setPayChannel(payChannel);
    					// yco.setTotal(BigDecimal.valueOf(Double.valueOf(total)));
    					ywtbCityOrderService.updateOrder(yco);
    				} else {
    					System.out.println("#####统一支付平台报错：" + orderData.getMsg());
    				}
    			} else {
    				System.out.println("#####统一支付平台报错：" + "未查询到状态");
    			}
    		} else {
    			System.out.println("#####处理方式：" + "不处理！！！！");
    		}
    	} else {
    		System.out.println("#####报错：" + "未查询到此订单");
    	}
    }

    /**
     * 取消订单
     * @param orderId
     */
    public void cancelOrder(String orderId, LoginInfo loginInfo) throws Exception {
    	YwtbCityOrder yco = ywtbCityOrderService.findById(orderId);
    	if(yco != null) {
    		if(StringUtils.equals(yco.getInstCode(), loginInfo.getInstCode())) {
    			String pay = getPayStatus(orderId);
    			// 支付平台状态：未支付/已关闭 ，可以取消订单
    			if(StringUtils.equals(pay, Pay.PAY_NO.getKey()) || StringUtils.equals(pay, Pay.PAY_CLOSED.getKey())) {
    				yco.setPay(Pay.PAY_CLOSED.getKey());
					ywtbCityOrderService.updateOrder(yco);
					// TODO 支付平台取消订单
    			} else {
    				// TODO 未支付/已取消/已关闭
    				throw new RequestSystemException("已完成支付的订单无法完成此操作");
    			}
    		} else {
    			throw new RequestSystemException("无法操作此订单");
    		}
    	} else {
    		throw new RequestSystemException("未查询到此订单");
    	}
    }
    
    public List<ReferPhySeal> getReferSealList(LoginInfo loginInfo){
    	SystemCustom custom = systemCustomService.findByBusinessLicenseForOne(loginInfo.getInstCode());
    	if(custom != null) {
    		List<ReferPhySeal> rtn = systemSealService.findReferSeal(custom.getId());
    		return rtn;
    	} else {
    		return new ArrayList<ReferPhySeal>();
    	}
    }
    
    public ReferPhySeal getReferSealByReferId(String referSealId, LoginInfo loginInfo) {
    	return systemSealService.getReferSealByReferId(referSealId);
    }
    
    public String getPayStatus(String orderId) {
    	YwtbCityOrder yco = ywtbCityOrderService.findById(orderId);
    	// 支付/未支付的订单可以更新，其他不可以
    	if(yco != null) {
			String tradeNo = yco.getTradeno();
			OutqQueryTransactionOrderDataVO orderData = payService.queryTransactionOrderResultInterface(tradeNo);
			// 支付成功，或已退款，或已关闭的订单，需要更新
			if(orderData != null) {
				if(orderData.getCode() == 0 && orderData.getData() != null) {
					String pay = orderData.getData().getTradeStatus();
					return pay;
				} else {
					return Pay.PAY_NO.getKey();
				}
    		} else {
    			throw new RequestSystemException("支付状态获取失败");
    		}
    	} else {
    		throw new RequestSystemException("未查询到此订单");
    	}
    }
    
    public WxSignature getWxSignature(String url) {
    	return GetWxSignatureUtil.getSignature(url);
    }
}
